﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;
using System.Collections;

using Optimization.Utilities;

namespace Optimization.Utilities
{
    /// <summary>
    /// General interface for optimization problem definition
    /// </summary>
    public interface IProblem
    {
        /// <summary>
        /// Evaluation of fitness function (problem)
        /// </summary>
        /// <param name="v">parameter of fitness function</param>
        /// <returns></returns>
        double Evaluate(Vector v);

        /// <summary>
        /// Predicted bounds of the problem
        /// </summary>
        /// <param name="mins">Vector of minimums</param>
        /// <param name="maxs">Vector of maximums</param>
        void GetBounds(out Vector mins, out Vector maxs);

        /// <summary>
        /// Feasibility of proposed solution
        /// </summary>
        /// <param name="v">propodsed solution</param>
        /// <returns>True if solution is feasible otherwise return false</returns>
        bool IsFeasible(Vector v);

        /// <summary>
        /// Generate random solution of problem
        /// </summary>
        /// <returns></returns>
        Vector RandomSolution();
    }

    /// <summary>
    /// General interface for solver
    /// </summary>
    public interface ISolver
    {
        /// <summary>
        /// Defines problem which have to be solved (minimized)
        /// </summary>
        /// <param name="cf">method for problem creation <see cref="T:Func{T}"/> can be used class method</param>
        void DefineProblem(Func<IProblem> cf);

        /// <summary>
        /// Returns the best know solution (suboptimal solution)
        /// </summary>
        /// <returns></returns>
        Vector GetSolution();

        /// <summary>
        /// Returns the value of best know solution (value of fitness function)
        /// </summary>
        /// <returns></returns>
        double GetSolutionValue();

        /// <summary>
        /// Runs one step of optimization algorithm
        /// </summary>
        void Step();

        /// <summary>
        /// Allows to adapt external solution. This is important function for method cooperation.
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="solutionValue"></param>
        void SetSolution(Vector solution, double solutionValue);

    }

}
